package StarterJWT

import (
	"context"
	"crypto/tls"
	"strings"
	"time"

	"gitee.com/go-spring2/spring-core/gs"
	pb "gitee.com/go-spring2/starter-geyser/proto" // proto directory path
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/credentials/insecure"
	"google.golang.org/grpc/encoding/gzip"
	"google.golang.org/grpc/keepalive"
)

type Config struct {
	Endpoint string `value:"${endpoint:=}"`
}

func init() {
	gs.Provide(NewClient, "${geyser}").Name("GeyserClient")
}

func NewClient(config Config) (pb.GeyserClient, error) {
	conn, err := dialGRPC(config.Endpoint)
	if err != nil {
		return nil, err
	}
	cli := pb.NewGeyserClient(conn)
	return cli, nil
}

func dialGRPC(endpoint string) (*grpc.ClientConn, error) {
	var opts []grpc.DialOption
	if strings.HasPrefix(endpoint, "https://") || strings.HasPrefix(endpoint, "grpcs://") {
		tlsConfig := &tls.Config{}
		creds := credentials.NewTLS(tlsConfig)
		opts = append(opts, grpc.WithTransportCredentials(creds))
	} else {
		opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))
	}
	opts = append(opts, grpc.WithKeepaliveParams(kacp))
	opts = append(opts, grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(1024*1024*1024), grpc.UseCompressor(gzip.Name)))

	addr := strings.TrimPrefix(endpoint, "https://")
	addr = strings.TrimPrefix(addr, "http://")
	addr = strings.TrimPrefix(addr, "grpcs://")

	return grpc.Dial(addr, opts...)
}

var kacp = keepalive.ClientParameters{
	Time:                10 * time.Second,
	Timeout:             time.Second,
	PermitWithoutStream: true,
}

type tokenAuth struct {
	token string
}

func (t tokenAuth) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
	return map[string]string{
		"x-token": t.token,
	}, nil
}

func (t tokenAuth) RequireTransportSecurity() bool {
	return true
}
